package com.android.broad;

import static com.android.broad.Constants.LOG_TAG;
import static com.android.broad.Constants.SQLITE_CREATE_EVENT_TABLE_SQL_REQUEST;
import static com.android.broad.Constants.SQLITE_DB_NAME;
import static com.android.broad.Constants.SQLITE_DB_VERSION;
import static com.android.broad.Constants.SQLITE_DEVICE_ID_COLUMN_NAME;
import static com.android.broad.Constants.SQLITE_EVENT_ID_COLUMN_NAME;
import static com.android.broad.Constants.SQLITE_EVENT_PARAMS_COLUMN_NAME;
import static com.android.broad.Constants.SQLITE_EVENT_TABLE_NAME;
import static com.android.broad.Constants.SQLITE_EVENT_TIMESTAMP_COLUMN_NAME;
import static com.android.broad.Constants.SQLITE_EVENT_TYPE_COLUMN_NAME;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

import com.android.broad.domain.Event;

public class Database {
  private static class DatabaseHelper extends SQLiteOpenHelper {

    public DatabaseHelper(final Context context) {
      super(context, SQLITE_DB_NAME, null, SQLITE_DB_VERSION);
    }

    @Override
    public void onCreate(final SQLiteDatabase db) {
      db.execSQL(SQLITE_CREATE_EVENT_TABLE_SQL_REQUEST);
    }

    @Override
    public void onUpgrade(final SQLiteDatabase db, final int oldVersion,
        final int newVersion) {
      Log.w(LOG_TAG, "Upgrading database from version " + oldVersion + " to "
          + newVersion + ", which will destroy all old data");
      db.execSQL("DROP TABLE IF EXISTS " + SQLITE_EVENT_TABLE_NAME);
      onCreate(db);
    }
  }

  private SQLiteDatabase db;
  private final DatabaseHelper dbHelper;

  public Database(final Context context) {
    dbHelper = new DatabaseHelper(context);
  }

  public void close() {
    dbHelper.close();
  }

  public void deleteEvent(final Event event) {
    db.delete(SQLITE_EVENT_TABLE_NAME, SQLITE_EVENT_ID_COLUMN_NAME + "="
        + event.eventId, null);
  }

  public List<Event> getEvents() {
    final Cursor cursor = db.query(SQLITE_EVENT_TABLE_NAME, null, null, null,
        null, null, null);
    if (cursor == null)
      return null;
    try {
      final ArrayList<Event> events = new ArrayList<Event>();
      Event event;
      while (true) {
        cursor.moveToNext();
        if (cursor.isAfterLast())
          break;
        event = new Event();
        event.eventId = cursor.getLong(cursor
            .getColumnIndexOrThrow(SQLITE_EVENT_ID_COLUMN_NAME));
        event.deviceId = cursor.getString(cursor
            .getColumnIndexOrThrow(SQLITE_DEVICE_ID_COLUMN_NAME));
        event.eventType = cursor.getString(cursor
            .getColumnIndexOrThrow(SQLITE_EVENT_TYPE_COLUMN_NAME));
        event.timestamp = cursor.getLong(cursor
            .getColumnIndexOrThrow(SQLITE_EVENT_TIMESTAMP_COLUMN_NAME));
        event.params = cursor.getString(cursor
            .getColumnIndexOrThrow(SQLITE_EVENT_PARAMS_COLUMN_NAME));
        events.add(event);
      }
      return events;
    } finally {
      cursor.close();
    }
  }

  public long insertEvent(final Event event) {
    final ContentValues initialValues = new ContentValues();
    initialValues.put(SQLITE_DEVICE_ID_COLUMN_NAME, event.deviceId);
    initialValues.put(SQLITE_EVENT_TYPE_COLUMN_NAME, event.eventType);
    initialValues.put(SQLITE_EVENT_TIMESTAMP_COLUMN_NAME, event.timestamp);
    initialValues.put(SQLITE_EVENT_PARAMS_COLUMN_NAME, event.params);
    return db.insert(SQLITE_EVENT_TABLE_NAME, null, initialValues);
  }

  public Database open() throws SQLException {
    db = dbHelper.getWritableDatabase();
    return this;
  }
}
